/*************************************************************************
 * @file: edge.h
 * @date: 01/04/2012
 * TOPOL v1_0 - (c)copyright 2012 TEC/UFF
 *************************************************************************
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 ************************************************************************/

#ifndef _EDGE
#define _EDGE

// includes
//----------

// forward declarations
//----------------------
class ICurve;
class Solid;
class HalfEdge;
class Vertex;

// enumerations
//--------------
enum EOrientation
{
  PLUS,
  MINUS
};


/*!
 * CLASS
 * Edge
 * 
 * This class implements the requirement for the topological entity named
 * Edge and sets all the necessary adjacency informations
 * 
 * @author Andre Pereira (andremaues@id.uff.br)
 * @version 1.0.0
 * @see HalfEdge
 * @see Curve
 * @see Vertex
 * @see Solid
 */
class Edge
{

public:

  ////////////////////////////////////////////////
  ///  Constructor and Destructor Declaration  ///
  ////////////////////////////////////////////////

  /**
   * @brief Constructs an edge and attaches it into a given Solid object
   * @param _s is a Solid object
   */
  Edge( Solid* _s );

  /**
   * @brief Destructs the Edge object
   */
  ~Edge();

  ////////////////////////////////////
  ///  PUBLIC Methods Declaration  ///
  ////////////////////////////////////

  /**
   * @brief Gets the edge identity
   * @param _v the vertex object associated to the added half-edge
   * @param _where the half-edge object associated to the added half-edge
   * @param _sign is used to inform the orientation of the added half-edge
   * @return HalfEdge* the pointer to the added half-edge
   */
  HalfEdge* addhe( Vertex* _v, HalfEdge* _where, EOrientation _sign );

  /**
   * @brief Gets the edge identity
   * @return size_t with the edge identity
   */
  size_t getEdgeno();

   /**
   * @brief Gets the previous edge
   * @return Edge* pointer to the previous edge object
   */
  Edge* getPrevEdge();

  /**
   * @brief Gets the next edge
   * @return Edge* pointer to the next edge object
   */
  Edge* getNextEdge();

  /**
   * @brief Gets the half-edge on the right
   * @return HalfEdge* pointer to the right half-edge
   */
	HalfEdge* getHe1();

  /**
   * @brief Gets the half-edge on the left
   * @return HalfEdge* pointer to the left half-edge
   */
	HalfEdge* getHe2();

  /**
   * @brief Gets the first vertex of the edge
   * @return Vertex* pointer to the first vertex
   */
  Vertex* getFirstVertex();

  /**
   * @brief Gets the second vertex of the edge
   * @return Vertex* pointer to the second vertex
   */
  Vertex* getSeconVertex();

  /**
   * @brief Verifies if the edge is selected or not
   * @return bool with selection status (true: selected, false: not selected)
   */
  bool isSelected();

  /**
   * @brief Sets an identity for the edge
   * @param _e the edge identity
   */
  void setEdgeno( size_t _e );

  /**
   * @brief Sets the half-edge on the right
   * @param _h1 the right half-edge
   */
  void setHe1( HalfEdge* _h1 );

  /**
   * @brief Sets the half-edge on the left
   * @param _h2 the left half-edge
   */
  void setHe2( HalfEdge* _h2 );

  /**
   * @brief Sets if the edge is selected or not
   * @param _select is used to define the selection status (true: selected, false: not selected)
   */
  void setSelection( bool _select );


private:

  ////////////////////////////////
  ///  Attributes Declaration  ///
  ////////////////////////////////

  /** @brief Identification of the edge, i.e., the edge identity */
  size_t m_edgeno;

  /** @brief Pointer to the previous edge */
	Edge* m_preve;

  /** @brief Pointer to the next edge */
	Edge* m_nexte;

  /** @brief Pointer to the half-edge on the right */
	HalfEdge* m_he1;

  /** @brief Pointer to the half-edge on the left */
	HalfEdge* m_he2;

  /** @brief Pointer to the geometric curve */
	ICurve* m_curve;

  /** @brief Flag to identify if the edge is selected or not */
  bool m_isSelected;		

  // TODO: 01/04/2012
  // add a bounding box

};

#endif
